package com.project.logging;

import com.alibaba.fastjson.JSON;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.project.logging.beans.ErrLog;
import com.project.logging.beans.OpLog;
import com.project.logging.service.ErrLogService;
import com.project.logging.service.OpLogService;
import jakarta.servlet.http.HttpServletRequest;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;

import java.lang.reflect.Method;
import java.util.Map;
import java.util.Objects;

@Aspect
@Component
public class LogAspect {

    @Autowired
    OpLogService opLogService;

    @Autowired
    ErrLogService errLogService;
    @Pointcut("@annotation(com.project.logging.MyLog)")
    public void logPointCut() {
    }

    @Pointcut("execution(* com.project.*.controller..*.*(..))")
    public void exceptionLogPointCut() {

    }

    @AfterReturning(value = "logPointCut()", returning = "keys")
    public void doAfterReturning(JoinPoint joinPoint, Object keys) {
        RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = (HttpServletRequest) requestAttributes.resolveReference(RequestAttributes.REFERENCE_REQUEST);
        OpLog opLog = null;
        try{
            MethodSignature signature = (MethodSignature) joinPoint.getSignature();
            Method method = signature.getMethod();
            String className = joinPoint.getTarget().getClass().getName();

            MyLog myLog = method.getAnnotation(MyLog.class);

            if (Objects.nonNull(myLog)) {
                opLog.setTitle(myLog.title());
                opLog.setMsg(myLog.message());
            }

            opLog.setMethod(className + "." + method.getName());
            opLog.setUrl(request.getRequestURI());

            opLogService.addLog(opLog);

        }catch (Exception e){
            e.printStackTrace();
        }


    }
    @AfterThrowing(pointcut = "exceptionLogPointCut()", throwing = "e")
    public void doAfterThrowing(JoinPoint joinPoint, Throwable e){
        RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = (HttpServletRequest) requestAttributes.resolveReference(RequestAttributes.REFERENCE_REQUEST);
        ErrLog errLog = null;
        Map m = request.getParameterMap();
        ObjectMapper objectMapper = new ObjectMapper();

        try{
            errLog.setName(e.getClass().getName());
            errLog.setMessage(ExceptionUtils.getStackTrace(e));
            errLog.setParam(JSON.toJSONString(objectMapper.writeValueAsString(m)));
            errLog.setUrl(request.getRequestURI());
            errLogService.addLog(errLog);

        }catch (Exception ee){
            ee.printStackTrace();
        }


    }




}
